package cn.yotta.user.core.server.iface.login.impl;

import cn.yotta.user.core.server.iface.login.PasswordEncoder;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;

import java.util.UUID;

/**
 * @author wyaoyao
 * @date 2022/11/12 17:10
 */
@SuppressWarnings({"UnstableApiUsage", "deprecation"})
public class DefaultPasswordEncoder implements PasswordEncoder {
    private static final HashFunction SHA512 = Hashing.sha512();
    private static final HashFunction MD5 = Hashing.md5();
    private static final Splitter SPLITTER = Splitter.on('@').trimResults();
    private static final Joiner JOINER = Joiner.on('@').skipNulls();

    @Override
    public String encode(CharSequence rawPassword) {
        if (rawPassword == null) {
            return null;
        }
        String salt = MD5.newHasher().putString(UUID.randomUUID().toString(), Charsets.UTF_8)
                .putLong(System.currentTimeMillis()).hash()
                .toString().substring(0, 4);
        String realPassword = SHA512.hashString(rawPassword + salt, Charsets.UTF_8)
                .toString().substring(0, 20);
        return JOINER.join(salt, realPassword);
    }

    @Override
    public boolean matches(CharSequence rawPassword, String encodedPassword) {
        Iterable<String> parts = SPLITTER.split(encodedPassword);
        String salt = Iterables.get(parts, 0, null);
        String realPassword = Iterables.get(parts, 1, null);
        if (salt == null || realPassword == null) {
            return false;
        }
        return Objects.equal(SHA512.hashString(rawPassword + salt, Charsets.UTF_8)
                .toString().substring(0, 20), realPassword);
    }

    public static void main(String[] args) {
        final DefaultPasswordEncoder defaultPasswordEncoder = new DefaultPasswordEncoder();
        final String encode = defaultPasswordEncoder.encode("123456");
        System.out.println(encode);
        boolean matches;
        // 53d3@c72bc2ac11ae3cb65cef
        // 5630@36706998a4ca8d395f75
        // fef7@8be7f357d7f6ec98eeca
        matches = defaultPasswordEncoder.matches("123456", "53d3@c72bc2ac11ae3cb65cef");
        System.out.println(matches);
        matches = defaultPasswordEncoder.matches("123456", "5630@36706998a4ca8d395f75");
        System.out.println(matches);
        matches = defaultPasswordEncoder.matches("123456", "fef7@8be7f357d7f6ec98eeca");
        System.out.println(matches);
    }
}
